package com.turing.post.salesmanage.impl;

import java.math.BigInteger;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;

import com.turing.post.capitalaccounts.util.BankAccount;
import com.turing.post.capitalaccounts.util.BankAccountDao;
import com.turing.post.capitalaccounts.util.SaleCapitalDetail;
import com.turing.post.capitalaccounts.util.SaleCapitalDetailDao;
import com.turing.post.common.util.PCPSCommonDao;
import com.turing.post.common.util.SysOperLog;
import com.turing.post.common.util.SysOperLogDao;
import com.turing.post.organization.util.IssueCompany;
import com.turing.post.organization.util.IssueCompanyDao;
import com.turing.post.organization.util.SaleBranch;
import com.turing.post.organization.util.SaleBranchDao;
import com.turing.post.salesmanage.util.DepositOrder;
import com.turing.post.salesmanage.util.DepositOrderDao;
import com.turing.post.salesmanage.util.DepositOrderPaidDetail;
import com.turing.post.salesmanage.util.DepositOrderPaidDetailBusiness;
import com.turing.post.salesmanage.util.DepositOrderPaidDetailDao;
import com.turing.post.salesmanage.util.SalesManageApplicationException;
import com.turing.post.salesmanage.util.SalesManageRespCode;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;
import com.turing.post.util.PCPSWebInput;

/**
 * 充值单付款信息（DepositOrderPaidDetail）
 * 
 * @author zxp
 * @Jan 17, 2013
 */
@Stateless(mappedName = "salesmanage.impl.DepositOrderPaidDetailBusinessImpl")
@Remote
@Local
public class DepositOrderPaidDetailBusinessImpl implements
		DepositOrderPaidDetailBusiness {

	@EJB(mappedName = "common.impl.SysOperLogDaoImpl")
	private SysOperLogDao sysOperLogDaoImpl;
	@EJB(mappedName = "common.impl.PCPSCommonDaoImpl")
	private PCPSCommonDao commonDaoImpl;

	@EJB(mappedName = "salesmanage.impl.DepositOrderPaidDetailDaoImpl")
	private DepositOrderPaidDetailDao depositOrderPaidDetailDaoImpl;

	@EJB(mappedName = "organization.impl.IssueCompanyDaoImpl")
	private IssueCompanyDao issueCompanyDaoImpl;

	@EJB(mappedName = "organization.impl.SaleBranchDaoImpl")
	private SaleBranchDao saleBranchDaoImpl;

	@EJB(mappedName = "capitalaccounts.impl.SaleCapitalDetailDaoImpl")
	private SaleCapitalDetailDao saleCapitalDetailDaoImpl;

	@EJB(mappedName = "salesmanage.impl.DepositOrderDaoImpl")
	private DepositOrderDao depositOrderDaoImpl;

	@EJB(mappedName = "capitalaccounts.impl.BankAccountDaoImpl")
	private BankAccountDao bankAccountDaoImpl;

	/**
	 * 异常抛出方法
	 * 
	 * @param error
	 * @throws PCPSApplicationException
	 */
	private void errException(String error) throws PCPSApplicationException {
		throw new SalesManageApplicationException(
				SalesManageApplicationException.ERRCODE_CATEGORY_APPLICATION,
				SalesManageRespCode.DEPOSIT_EXCEPTIONCODE, error);
	}

	// 充值单付款
	@Override
	public BigInteger insertDepositOrderPaidDetail(PCPSWebInput webInput,
			DepositOrderPaidDetail dopd) throws PCPSApplicationException {
		if (webInput.getOperId() == null) {
			return BigInteger.ZERO;
		}
		// 对象为NULL
		if (dopd == null) {
			errException("付款充值单为空!");
		}
		// 查询充值单
		DepositOrder dor = depositOrderDaoImpl.getDepositOrderForUpdate(dopd
				.getDepositOrderId());
		if (dor == null) {
			errException("充值单编号错误未查询到充值单!");
		}
		// 判断录入确认状态
		if (!dor.getOrderStatus().equals(
				DepositOrder.DEPORDER_ORDERSTATUS_INPUTCONFIRM)) {
			errException("只有录入确认状态下才可付款");
		}
		// 判断收款人和付款人是否为同一人
		if (dopd.getPaidAccountId() != null && dopd.getPayeeAccountId() != null) {
			if (dopd.getPaidAccountId().intValue() == dopd.getPayeeAccountId()
					.intValue()) {
				errException("收款人和付款人不能为同一人!");
			}
		}
		// 现金付款收款人编号为空
		if (dopd.getPayeeAccountId() != null) {
			// 收款人---->发卡商银行检查
			List<BankAccount> baList = bankAccountDaoImpl
					.getBankAccountDropdown(webInput,
							BankAccount.BANKTYPE_ISSUECOMPANY);
			boolean tag = false;
			for (BankAccount iba : baList) {
				if (dopd.getPayeeAccountId().compareTo(iba.getBankAccountId()) == 0) {
					tag = true;
				}
			}
			if (!tag) {
				throw new SalesManageApplicationException(
						SalesManageApplicationException.ERRCODE_CATEGORY_APPLICATION,
						SalesManageRespCode.SALESBUSINESS_ARGS_NULL,
						"收款人银行账户不为发卡商银行账户!");
			}
		}
		// 付款时间
		dopd.setTranTime(commonDaoImpl.getDatabaseSysTime());
		// 付款金额
		if (dopd.getPaidAmount() == null
				|| dopd.getPaidAmount().compareTo(BigInteger.ZERO) <= 0) {
			errException("付款金额有误!");
		}
		dopd.setOperId(webInput.getOperId());
		BigInteger sopdId = commonDaoImpl.getUniqueIntegerKey();
		// 主键
		dopd.setDepositOrderPaidId(sopdId);
		// 只记录现金账务
		if (dopd.getPaidType().equals(
				DepositOrderPaidDetail.DEPOSITOPD_PAIDTYPE_CASH)) {
			// 插入销售机构资金明细表（SaleCapitalDetail）
			SaleCapitalDetail scd = new SaleCapitalDetail();
			scd.setSaleBranchNo(dor.getSaleBranchNo());// 销售机构号
			// 获取发卡商表中日期
			IssueCompany ic = issueCompanyDaoImpl
					.getIssueCompanyByIssueCompanyNo(PCPSUtil.getICNoByBranchNo(dor.getSaleBranchNo()
							));
			// 判断是否为日终(交易)状态
			if (ic.getStatus().equals(IssueCompany.ISSUECOMPANY_NORMAL_ENDDAY)) {
				errException("发卡商为正在日终状态禁止付款!");
			}
			scd.setTranDate(ic.getTranDate());
			scd.setTranType(SaleCapitalDetail.TRANTYPE_RECEIVECASH);// 05 – 收到现金
			scd.setTicketId(sopdId);// 相关业务单ID
			scd.setTranTime(commonDaoImpl.getDatabaseSysTime());// 交易时间
			scd.setCreditDeposit(BigInteger.ZERO);// 信用度存入 decimal(16) Not
			scd.setCreditWithdraw(BigInteger.ZERO);// 信用度支出 decimal(16) Not
			scd.setCashDeposit(dopd.getPaidAmount());// 现金存入
			scd.setCashWithdraw(BigInteger.ZERO);// 现金支出 decimal(16) Not Null
			scd.setOperId(webInput.getOperId());// 操作员ID
			scd.setRemark("销售单付款"); // 摘要
			saleCapitalDetailDaoImpl.insertSaleCapitalDetail(scd);
			// 修改销售商分支机构（SaleBranch）现金库存
			SaleBranch sb = saleBranchDaoImpl.getSaleBranchForUpdate(dor
					.getSaleBranchNo());
			if (sb == null) {
				errException("更新销售商分支机构当日现金余额失败，销售商分支机构未找到!");
			}
			sb.setCash(sb.getCash().add(dopd.getPaidAmount()));
			saleBranchDaoImpl.updateSaleBranch(sb);
			// 日志记录
			sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
					SysOperLog.operType_Edit, "充值单付款", "DepositOrderId:"
							+ dor.getDepositOrderId());
		}

		// 新增
		depositOrderPaidDetailDaoImpl.insertDepositOrderPaidDetail(dopd);
		// 设置充值单表付款金额
		dor.setAlreayPaidAmount(dor.getAlreayPaidAmount().add(
				dopd.getPaidAmount()));
		// 更新充值单表付款金额
		depositOrderDaoImpl.updateDepositOrder(dor);
		return sopdId;
	}

	// 修改图片信息
	@Override
	public void updateDepositOrderPaidDetail(PCPSWebInput webInput,
			DepositOrderPaidDetail depositOrderPaidDetail)
			throws PCPSApplicationException {
		if (webInput.getOperId() == null) {
			return;
		}
		if (depositOrderPaidDetail.getVoucherImageId() == null) {
			return;
		}
		DepositOrderPaidDetail dopd = depositOrderPaidDetailDaoImpl
				.getDepositOrderPaidDetailForUpdate(depositOrderPaidDetail
						.getDepositOrderPaidId());
		if (dopd == null) {
			errException("待修改充值单付款信息不存在!");
		}
		// 修改图片
		dopd.setVoucherImageId(depositOrderPaidDetail.getVoucherImageId());
		depositOrderPaidDetailDaoImpl.updateDepositOrderPaidDetail(dopd);
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "修改凭证图片", "DepositOrderId:"
						+ dopd.getDepositOrderId());
	}

	// 充值单付款撤销
	@Override
	public void insertDepositOrderPaidDetailCancel(PCPSWebInput webInput,
			BigInteger depositOrderPaidId) throws PCPSApplicationException {
		if (webInput.getOperId() == null) {
			return;
		}
		// 需要撤销的充值单付款信息
		DepositOrderPaidDetail dopd = depositOrderPaidDetailDaoImpl
				.getDepositOrderPaidDetailForUpdate(depositOrderPaidId);
		if (dopd == null) {
			errException("所要撤销充值单付款信息系统中不存在!");
		}
		// 撤销付款
		DepositOrderPaidDetail dopdCancel = new DepositOrderPaidDetail();
		// 充值单
		DepositOrder depositOrder = depositOrderDaoImpl
				.getDepositOrderForUpdate(dopd.getDepositOrderId());
		// 判断录入确认状态
		if (!depositOrder.getOrderStatus().equals(
				DepositOrder.DEPORDER_ORDERSTATUS_INPUTCONFIRM)) {
			errException("只有录入确认状态下才可撤销付款");
		}
		// 操作员号
		if (webInput.getOperId() == null) {
			errException("撤销充值单付款操作员号为空!");
		}
		// 主键
		dopdCancel.setDepositOrderPaidId(commonDaoImpl.getUniqueIntegerKey());
		// 撤销记录 付款撤销时间
		dopdCancel.setTranTime(commonDaoImpl.getDatabaseSysTime());
		dopdCancel.setDepositOrderId(depositOrder.getDepositOrderId());
		dopdCancel.setPaidType(dopd.getPaidType());
		dopdCancel
				.setPaidAmount(BigInteger.ZERO.subtract(dopd.getPaidAmount()));// 撤销的付款金额,负数
		dopdCancel.setPayeeAccountId(dopd.getPayeeAccountId());// 收款人
		dopdCancel.setPaidAccountId(dopd.getPaidAccountId());// 付款人
		dopdCancel.setVoucherNo(dopd.getVoucherNo());// 凭证号
		dopdCancel.setVoucherRemark(dopd.getVoucherRemark());// 凭证摘要
		dopdCancel.setVoucherImageId(dopd.getVoucherImageId());// 凭证图片编号
		dopdCancel.setOperId(webInput.getOperId());
		dopdCancel.setCancelDepositOrderPaidId(dopd.getDepositOrderPaidId());// 取消充值单付款ID
		dopdCancel.setRemark(dopd.getRemark());// 备注

		// 只记录现金账务
		if (dopd.getPaidType().equals(
				DepositOrderPaidDetail.DEPOSITOPD_PAIDTYPE_CASH)) {
			// 插入销售机构资金明细表（SaleCapitalDetail）
			SaleCapitalDetail scd = new SaleCapitalDetail();
			scd.setSaleBranchNo(depositOrder.getSaleBranchNo());// 销售机构号
			// 获取发卡商表中日期
			IssueCompany ic = issueCompanyDaoImpl
					.getIssueCompanyByIssueCompanyNo(PCPSUtil.getICNoByBranchNo(depositOrder
							.getSaleBranchNo()));
			scd.setTranDate(ic.getTranDate());
			scd.setTranType(SaleCapitalDetail.TRANTYPE_CANCELRECEIVECASH);// 15
			// –
			// 收到现金
			scd.setTicketId(dopd.getDepositOrderPaidId());// 相关业务单ID
			scd.setTranTime(commonDaoImpl.getDatabaseSysTime());// 交易时间
			scd.setCreditDeposit(BigInteger.ZERO);// 信用度存入 decimal(16) Not
			scd.setCreditWithdraw(BigInteger.ZERO);// 信用度支出 decimal(16) Not
			scd.setCashDeposit(BigInteger.ZERO.subtract(dopd.getPaidAmount()));// 现金存入
			scd.setCashWithdraw(BigInteger.ZERO);// 现金支出 decimal(16) Not Null
			scd.setOperId(webInput.getOperId());// 操作员ID
			scd.setRemark("充值单付款撤销"); // 摘要
			saleCapitalDetailDaoImpl.insertSaleCapitalDetail(scd);
			// 修改销售商分支机构（SaleBranch）现金库存
			SaleBranch sb = saleBranchDaoImpl
					.getSaleBranchForUpdate(depositOrder.getSaleBranchNo());
			if (sb == null) {
				errException("更新销售商分支机构当日现金余额失败，销售商分支机构未找到!");
			}
			sb.setCash(sb.getCash().add(scd.getCashDeposit()));
			saleBranchDaoImpl.updateSaleBranch(sb);
		}

		// 新增
		depositOrderPaidDetailDaoImpl.insertDepositOrderPaidDetail(dopdCancel);
		// 修改需要撤销的付款记录
		dopd.setCancelDepositOrderPaidId(dopdCancel.getDepositOrderPaidId());
		depositOrderPaidDetailDaoImpl.updateDepositOrderPaidDetail(dopd);
		// 设置充值单表付款金额
		depositOrder.setAlreayPaidAmount(depositOrder.getAlreayPaidAmount()
				.add(dopdCancel.getPaidAmount()));
		depositOrderDaoImpl.updateDepositOrder(depositOrder);
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "充值单付款撤销", "DepositOrderId:"
						+ depositOrder.getDepositOrderId());
	}
}
